<?php

namespace App\Supports\WithdrawFreelance\LinkInq;

use Exception;
use App\Models\User;
use App\Models\BankCard;
use App\Models\Freelance;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use GuzzleHttp\Client;
use Brick\Math\RoundingMode;

class LinkInq
{
	protected $request_url = 'https://www.linkinq.com/sop/gateway';

	public function __construct(User $user)
	{
		$this->config = config('linkinq');
		$this->app_id = $this->config['other_app_id'];

		$this->private_key = $this->config['other_private_key'];
		
		$this->localUser = $user;

		if (!$this->localUser->isPhoneBound()) {
			abort(400, '会员账号手机号码未绑定');
		}
	}
	
	protected function getGuzzleClient()
	{
		return new Client(['Content-Type' => 'application/x-www-form-urlencoded']);
	}

	
	public function register()
	{
		try {
			$method = "settle.register.api.register";
			$params = [
				'name' => request('real_name'),
				'mobile' => $this->localUser->phone,
				'idType' => 'IDENTITY',
				'idNo' => request('id_no'),
				'idCardFront' => $this->base64EncodeImage(request('id_card_front')),
				'idCardBack' =>  $this->base64EncodeImage(request('id_card_back')),
			];
			$response = $this->commonFieldHandle($params,$method);
			
			Log::debug(json_encode($response));
			if($response['code'] != '10000'){
				abort(400, "提现账户创建失败:{$response['msg']}");
			}

			$response = json_decode($response['response'],true);
			
			if ($response['code'] == '0000') {
				Freelance::create([
					'real_name' => request('real_name'),
					'id_no' => request('id_no'),
					'id_card_front' => request('id_card_front'),
					'id_card_back' => request('id_card_back'),
					'is_auth' => true,
					'pers_no' => $response['persNo'],
					'user_id' => $this->localUser->id,
				]);
				
			} else {
				abort(400, "提现账户创建失败:{$response['message']}");
			}
		} catch (Exception $exception) {
			abort(400, $exception->getMessage());
		}
		
		return $this->localUser;
	}

	public function getCardNo($withdraw_method){
		$recvCardNo = '';
		if($withdraw_method == 'wxpay'){
			abort(400, "暂不支持微信提现");
			$recvCardNo = $this->localUser->wx_openid;
		}elseif($withdraw_method=='alipay'){
			$recvCardNo = $this->localUser->alipay_user_no;
		}else{
			$recvCardNo =  !empty($this->localUser->bankCards->find(request()->bank_card_id)) 
							? $this->localUser->bankCards->find(request()->bank_card_id)->cert_number : '';
		}
		if(empty($recvCardNo)){

			abort(400, "提现账户不能为空");
		}
		return $recvCardNo;

	}

	public function getBankName($withdraw_method){
		$bankName = '';
		if($withdraw_method == 'wxpay'){
			$bankName = '微信钱包';
		}elseif($withdraw_method == 'alipay'){
			$bankName = '支付宝';
		}else{
			$bankName = !empty($this->localUser->bankCards->find(request()->bank_card_id)) 
						? $this->localUser->bankCards->find(request()->bank_card_id)->card_name : '';
		}
		if(empty($bankName)){

			abort(400, "收款方不能为空");
		}
		return $bankName;

	}

	public function getRand(){
		$rand = time().rand('10000','99999');
		return $rand;
	}

	public function withdraw($chargeFee,$actualAmount)
	{
		try {
			$method = "settle.remit.api.payment";
			$withdraw_method = request()->withdraw_method;

			$recv_card_no = $this->getCardNo($withdraw_method);
			$bank_name = $this->getBankName($withdraw_method);

			if($withdraw_method == 'wxpay'){

				$this->app_id = $this->config['wx_app_id'];

				$this->private_key = $this->config['wx_private_key'];
			}
			
			$remitDetailList[0] = [
				'custOrderNo' => $this->getRand(),
				'recvCustName' => $this->localUser->freelance->real_name,
				'recvMobile' => $this->localUser->phone,
				'recvIdType' => 'IDENTITY',
				'recvIdNo' => $this->localUser->freelance->id_no,
				'recvCardNo' => $recv_card_no,
				'recvBankName' => $bank_name,
				'remark' => '一加二购提现',
				'orderAmt' => $actualAmount,
			];

			$params = [
				'custBatchNo' => $this->getRand(),
				'batchNum' => 1,
				'batchAmt' => $actualAmount,
				'serverCallbackUrl' => 'https://'.$_SERVER['HTTP_HOST']."/api/v1/withdraws/freelances/notify",
				'remitDetailList' => $remitDetailList,
				'recvType' =>  config("site.withdraw.linkINQ_methods.{$withdraw_method}"),
			];

			$response = $this->commonFieldHandle($params,$method);
			
			
			Log::debug(json_encode($response));
			if($response['code'] != '10000'){
				abort(400, "提现失败:{$response['msg']}");
			}

			$response = json_decode($response['response'],true);
			
			if ($response['code'] == '0000') {
				$withdraw = $this->localUser->withdraws()->create([
					'charge_type' => 'linkINQ',
					'method' => request('withdraw_method'),
					'channel' => '灵鹊云灵活用工',
					'plat_batch_no' => $response['platBatchNo'],
					'status' => 'pending',
					'charge_amount' => $chargeFee,
					'target_amount' => request()->withdraw_amount,
				]);
				
			} else {
				abort(400, "提现失败:{$response['message']}");
			}
		} catch (Exception $exception) {
			abort(400, $exception->getMessage());
		}
		
		return $this->localUser;
	}


	public function commonFieldHandle($params,$method){

			$paramMap["biz_content"]=json_encode($params);
			$paramMap["merchant_request_no"]=$this->getRand();
			$paramMap["method"]=$method;
			$paramMap["sign_type"]="RSA2";

			if (app()->environment('production')) {
				$this->app_id = "10220324928010";
			}
			$paramMap["app_id"]=$this->app_id;
			$paramMap["timestamp"]=date('Y-m-d H:i:s');
			$paramMap["version"]="1.0";
			ksort($paramMap);
			$tostr = $this->toQueryString($paramMap);

			$sign = $this->rsaSign($tostr,$this->private_key);

			$paramMap["sign"]=$sign;

			$result = $this->curl_request($this->request_url,$paramMap);
			$response = json_decode($result, true);
			return $response;


	}

	function base64EncodeImage ($image_file) {
  		$base64_image = '';
  		$image_info = getimagesize($image_file);
  		$image_data = file_get_contents($image_file);
  		$base64_image = base64_encode($image_data);
  		return $base64_image;
	}

	public static function curl_request($url,$post, $timeout=120, $json=false, $Multipart =false,$headers=null){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);

        #curl_setopt($curl, CURLOPT_USERAGENT, 'YOP_PHP_Client_API');
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);


        if($headers!=null) {
            $headerArray=array();
            foreach ($headers as  $key => $value) {
                array_push($headerArray,$key.":".$value);
            }
            curl_setopt($curl, CURLOPT_HTTPHEADER,  $headerArray);
        }

        if($post) {
            curl_setopt($curl, CURLOPT_POST, 1);
            //curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($post)?http_build_query($post):$post);
            curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($post)?http_build_query($post,null,'&'):$post);

        }



        if($Multipart){
            curl_setopt ($curl, CURLOPT_SAFE_UPLOAD, false);
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
        }
        $TLS = substr($url, 0, 8) == "https://" ? true : false;
        if($TLS) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
        }

        curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
        $data = curl_exec($curl);
        if (curl_errno($curl)) {
            return curl_error($curl);
        }
        curl_close($curl);


        if ($json){
            return json_decode($data,true);
        }
        return $data;

    }

	//数组转换为字符串
  
    public function toQueryString($paramMap)
    {
        $StrQuery = "";
        foreach ($paramMap as $k => $v) {
            $StrQuery .= strlen($StrQuery) == 0 ? "" : "&";
            $StrQuery .= $k . "=" . $v;
        }
        return $StrQuery;
    }

    /**
     * RSA签名
     * @param $data 待签名数据
     * @param $private_key 私钥字符串
     * return 签名结果
     */
    function rsaSign($data, $private_key,$type = 'RSA2') {

        $private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($private_key, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
        #var_dump($private_key);
        extension_loaded('openssl') or die('php需要openssl扩展支持');
        $res=openssl_get_privatekey($private_key);
 
        if($res)
        {
            if($type == 'RSA'){
                openssl_sign($data, $sign,$res);
            }elseif($type == 'RSA2'){
                //OPENSSL_ALGO_SHA256
                openssl_sign($data, $sign,$res,OPENSSL_ALGO_SHA256);
            }
            openssl_free_key($res);
        }else {
            exit("私钥格式有误");
        }
        $sign = base64_encode($sign);
        return $sign;
    }
 
   
}
